package gameStates.absGamesStates.gui;

import main.listeners.listenerClasses.GameListener;
import main.listeners.listenerClasses.gui.ChatActivatedEvent;
import main.listeners.listenerClasses.gui.ConsoleToggleEvent;
import main.listeners.listenerClasses.gui.GUIListener;
import main.listeners.listenerClasses.gui.IngameChangedEvent;
import main.listeners.listenerClasses.gui.LoginEvent;
import main.listeners.listenerClasses.gui.LoginListener;
import main.listeners.listenerClasses.gui.LogoutEvent;
import main.listeners.listenerClasses.gui.ScoreBoardToggleEvent;
import main.listeners.listenerClasses.gui.SpawnMenuChangedEvent;
import main.listeners.listenerClasses.loading.LoadingAbortedEvent;
import main.listeners.listenerClasses.loading.LoadingListener;
import main.listeners.listenerClasses.loading.LoadingStartedEvent;
import main.listeners.listenerClasses.loading.LoadingStoppedEvent;
import gameStates.absGamesStates.network.AbsClientState;
import gameStates.absGamesStates.network.AbsServerState;
import gameStates.gui.GUIState;
import gameStates.gui.GraphicChangeLoadingState;
import gameStates.gui.MapLoadingState;
import gameStates.passes.AbsPassManagerState;
import interfaces.menu.AbsMenu;

public abstract class AbsMenuState extends GUIState {
	
	protected boolean gameInitialized, consoleActive, activeBeforeGraphicsChange;
	protected AbsClientState clientState;
	protected AbsServerState serverState;
	
	public AbsMenuState(AbsPassManagerState passManagerState, boolean init, AbsClientState clientState, 
			AbsServerState serverState) {
		super("menu", passManagerState, init);
		this.clientState = clientState;
		this.serverState = serverState;
		
		addIngameListener();
	}
	
	protected void addIngameListener() {
		addListenerToClearer(new GUIListener() {
			@Override
			public void ingameChanged(IngameChangedEvent event) {
				setActive(!event.isIngame());
				if(!event.isIngame()) enableInput(!consoleActive);
			}

			@Override
			public void consoleToggled(ConsoleToggleEvent event) {
				consoleActive = event.getValue();
				enableInput(!consoleActive);
			}
			
			@Override
			public void spawnMenuChanged(SpawnMenuChangedEvent event) {}
			@Override
			public void scoreBoardToggled(ScoreBoardToggleEvent event) {}
			@Override
			public void chatActivated(ChatActivatedEvent event) {}
		});
		
		addListenerToClearer(new GameListener() {
			@Override
			public void gameStarted() {
				updateGameInitialized(true);
			}
			
			@Override
			public void gameFinished() {
				updateGameInitialized(false);
			}
			
			@Override
			public void gameDestroyed() {
				updateGameInitialized(false);
			}
		});
		
		addListenerToClearer(new LoadingListener() {
			@Override
			public void loadingStarted(LoadingStartedEvent event) {
				setActive(false);
				activeBeforeGraphicsChange = event.getLoadingState() instanceof GraphicChangeLoadingState;
			}
			
			@Override
			public void loadingStopped(LoadingStoppedEvent event) {
				if(activeBeforeGraphicsChange) setActive(true);
			}
			
			@Override
			public void loadingAborted(LoadingAbortedEvent event) {
				if(event.getLoadingState() instanceof MapLoadingState) setActive(true);
			}
		});
		
		addListenerToClearer(new LoginListener() {
			@Override
			public void userLoggedOut(LogoutEvent event) {
				setActive(false);
			}
			
			@Override
			public void userLoggedIn(LoginEvent event) {
				setActive(true);
			}
		});
	}
	
	protected void updateGameInitialized(boolean init) {
		gameInitialized = init;
		enableContinueButton(gameInitialized);
		setGameStarted(gameInitialized);
	}
	
	public abstract AbsMenu getMenu();
	
	public abstract void enableContinueButton(boolean enable);
	
	public abstract void setGameStarted(boolean gameStarted);
	
	public boolean gameInitialized() { return gameInitialized; }
	
	public AbsClientState getClientState() { return clientState; }
	
	public AbsServerState getServerState() { return serverState; }
}